Skip to content

fix(linter): detect real function call sites#48

Merged
alphacrack merged 2 commits into
alphacrack:developmentfrom
Sanjays2402:fix/unused-function-boundary
Jul 23, 2026
Merged

fix(linter): detect real function call sites#48
alphacrack merged 2 commits into
alphacrack:developmentfrom
Sanjays2402:fix/unused-function-boundary

Conversation

@Sanjays2402

Copy link
Copy Markdown
Contributor

Closes #31

Summary

Requires a Devanagari-aware function call site when checking whether a declared function is used. Longer identifiers, strings, and comments no longer hide unused-function warnings.

Motivation / Audit Reference

Closes #31.

Test Evidence

  • pytest -v runs green locally
  • Coverage is at or above the critical-module gate (cli / transpile / linter ≥90%)
  • New tests added for any new behavior or regression
  • python -m maithili_dsl examples/*.dmai smoke-tested the examples
  • python -m maithili_dsl --version shows the expected version

144 tests passed; overall coverage is 95% and linter coverage is 90%. The two focused regressions failed without the source fix and passed with it. Ruff check passed; Ruff format reports the same two pre-existing files on the baseline branch.

Security Considerations

N/A.

Breaking Changes

None.

Checklist

  • CHANGELOG.md updated (Unreleased section)
  • Version bumped if this is a release PR
  • No new runtime dependencies added (or justification provided below)
  • Docs updated if user-visible behavior changed

Match declared functions at Devanagari-aware identifier boundaries and ignore string/comment contents when checking usage. Add regressions for longer identifiers and string literals.
@Sanjays2402
Sanjays2402 requested a review from alphacrack as a code owner July 19, 2026 17:17

@alphacrack alphacrack left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving — this is the right shape: reusing _make_keyword_pattern for Devanagari-aware boundaries and _tokenize_preserving_strings to skip string contents, with tests covering both failure modes from #31 (substring identifier, call-shaped text inside a string). CI is green including ci-ok.

Two non-blocking notes:

  1. Known behavior change to document: requiring name( means passing a function as a value (x = जोड़, map(जोड़, …)) now counts as unused and warns. For learner-oriented code that is an acceptable trade-off, but please add one line to the CHANGELOG entry acknowledging it, so it reads as a decision rather than an accident.
  2. Micro-nit: call_pattern is rebuilt per declared function on every lint call. Harmless at this scale — mentioning only in case you touch this again.

Heads-up: this branch's CHANGELOG hunk predates the entry merged from #38, so you may hit a trivial conflict on the ### Fixed section — a quick rebase on development will sort it.

@alphacrack alphacrack added this to the v0.4.0 milestone Jul 20, 2026
@alphacrack alphacrack added bug Something isn't working area:linter maithili_dsl/transpiler/linter.py P3 Low priority: nice to have labels Jul 20, 2026
@Sanjays2402

Copy link
Copy Markdown
Contributor Author

Thanks! Added a CHANGELOG note calling out the trade-off explicitly — since a call now needs name(, passing a function as a value (x = जोड़, map(जोड़, …)) counts as unused and warns. Framed it as a deliberate choice favoring clarity for learner code.

On the call_pattern nit: it actually depends on the per-function loop variable f (re.compile(_make_keyword_pattern(f).pattern + r'\s*('), so it can't be hoisted out of the loop without changing behavior — left it as-is. All 144 tests green.

@alphacrack
alphacrack merged commit 090f90f into alphacrack:development Jul 23, 2026
9 checks passed
alphacrack added a commit that referenced this pull request Jul 23, 2026
* ci(publish): add PyPI publish pipeline via Trusted Publishing (OIDC)

Adds a two-stage publish workflow that ships python_maithili to
PyPI without storing long-lived API tokens in GitHub. Three
triggers, three behaviours:

  - release.published (non-prerelease) -> publishes to production
    PyPI (environment: pypi, with optional manual-approval gate)
  - release.published (prerelease) OR workflow_dispatch target=testpypi
    -> publishes to TestPyPI (environment: testpypi, staging/verification)
  - workflow_dispatch target=build-only -> builds + twine-checks, no
    network publish (credential-free dry run)

Every path runs the same build job first: python -m build, twine
check --strict, install the wheel in a clean venv, run the full
pytest suite against the installed wheel. Only if the wheel itself
passes the test suite does anything get uploaded. The production
job additionally verifies that the GitHub Release tag (v0.X.Y)
matches __version__ in the package and refuses to publish on
mismatch — preventing accidental version drift.

Trusted Publishing was chosen over API tokens because:

  - No secrets to rotate or leak.
  - Scoped per environment: the pypi environment can be gated with
    required reviewers and tag-only deployment branches.
  - PyPI binds the trust to (owner, repo, workflow filename,
    environment), so a fork or a different workflow cannot publish
    on your behalf even if it runs on this repo.

The one-time setup (register Trusted Publisher on PyPI and pending
publisher on TestPyPI, create pypi + testpypi GitHub Environments)
is documented in the new docs/RELEASE.md, along with the routine
release checklist, version-bump convention, and recovery procedure
for bad releases.

build + twine added to requirements-dev.txt so contributors can
reproduce the build locally before opening a release PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: add OSS community health files

- Issue templates (bug report, feature request, Maithili keyword proposal)
- CODE_OF_CONDUCT.md (Contributor Covenant 2.1)
- SUPPORT.md and issue template contact links (security reporting routed privately)
- CODEOWNERS for security-sensitive paths
- Label guide in CONTRIBUTING.md; CoC links in README/CONTRIBUTING
- Mark BACKLOG.md as historical (tracking moved to GitHub Issues)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci: add ci-ok aggregate gate job + Dependabot config

- ci-ok: single required-status-check target that fails if any test
  matrix leg fails, so branch protection survives matrix changes
- dependabot.yml: weekly github-actions + pip updates targeting
  development, labeled infra/needs-triage

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(linter): accept augmented assignments

Strip augmented-assignment operators before validating the target name. Add regression coverage for every reported arithmetic operator.

* chore(deps): bump actions/upload-artifact from 4 to 7 (#14)

Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump actions/setup-python from 5 to 6 (#15)

Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump actions/checkout from 4 to 7 (#16)

Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump actions/download-artifact from 4 to 8 (#17)

Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](actions/download-artifact@v4...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): update twine requirement from <6,>=4.0 to >=6.2.0,<7 (#18)

Updates the requirements on [twine](https://github.com/pypa/twine) to permit the latest version.
- [Release notes](https://github.com/pypa/twine/releases)
- [Changelog](https://github.com/pypa/twine/blob/main/docs/changelog.rst)
- [Commits](pypa/twine@4.0.0...6.2.0)

---
updated-dependencies:
- dependency-name: twine
  dependency-version: 6.2.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): update pytest-cov requirement (#20)

Updates the requirements on [pytest-cov](https://github.com/pytest-dev/pytest-cov) to permit the latest version.
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](pytest-dev/pytest-cov@v4.1.0...v7.1.0)

---
updated-dependencies:
- dependency-name: pytest-cov
  dependency-version: 7.1.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): update pytest-timeout requirement (#21)

Updates the requirements on [pytest-timeout](https://github.com/pytest-dev/pytest-timeout) to permit the latest version.
- [Commits](pytest-dev/pytest-timeout@2.2.0...2.4.0)

---
updated-dependencies:
- dependency-name: pytest-timeout
  dependency-version: 2.4.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore: drop Python 3.9 support (EOL Oct 2025) (#52)

Removes 3.9 from the CI matrix, bumps requires-python to >=3.10, drops
the 3.9 classifier from pyproject.toml and setup.py, and updates the
README support line. Unblocks Dependabot PRs #19 (pytest 9) and #22
(build 1.5) which dropped 3.9 support.

Closes #44

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* chore(deps-dev): update pytest requirement from <9,>=7.4 to >=9.1.1,<10 (#19)

Updates the requirements on [pytest](https://github.com/pytest-dev/pytest) to permit the latest version.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@7.4.0...9.1.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 9.1.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): update build requirement from <2,>=1.0 to >=1.5.0,<2 (#22)

Updates the requirements on [build](https://github.com/pypa/build) to permit the latest version.
- [Release notes](https://github.com/pypa/build/releases)
- [Changelog](https://github.com/pypa/build/blob/main/CHANGELOG.rst)
- [Commits](pypa/build@1.0.0...1.5.0)

---
updated-dependencies:
- dependency-name: build
  dependency-version: 1.5.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix(linter): detect real function call sites (#48)

* fix(linter): detect real function call sites

Match declared functions at Devanagari-aware identifier boundaries and ignore string/comment contents when checking usage. Add regressions for longer identifiers and string literals.

* docs(changelog): note function-as-value trade-off for unused check

* docs: add examples/README.md describing each example program (fixes #41) (#47)

Co-authored-by: MOHAMMED HANAN M T P <hanu@example.com>
Co-authored-by: Bishwas Jha <18480504+alphacrack@users.noreply.github.com>

* ci: enforce coverage gate with fail_under = 85 (fixes #42) (#46)

Co-authored-by: MOHAMMED HANAN M T P <hanu@example.com>
Co-authored-by: Bishwas Jha <18480504+alphacrack@users.noreply.github.com>

* release: v0.4.0 (#53)

Bump version to 0.4.0 across __init__.py, pyproject.toml (setup.py reads
from __init__). Finalize CHANGELOG: promote [Unreleased] to [0.4.0] dated
2026-07-23, consolidate the fixed entries, and add the coverage-gate (#42)
and examples README (#41) entries that were merged without changelog lines.

First PyPI publish since 0.2.0 (0.3.0 was never pushed to the index).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Bishwas Jha <bishwasjha@Bishwass-MacBook-Pro.local>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Sanjay Santhanam <51058514+Sanjays2402@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MOHAMMED HANAN M T P <91409429+hanu-14@users.noreply.github.com>
Co-authored-by: MOHAMMED HANAN M T P <hanu@example.com>
alphacrack added a commit that referenced this pull request Jul 23, 2026
* ci(publish): add PyPI publish pipeline via Trusted Publishing (OIDC)

Adds a two-stage publish workflow that ships python_maithili to
PyPI without storing long-lived API tokens in GitHub. Three
triggers, three behaviours:

  - release.published (non-prerelease) -> publishes to production
    PyPI (environment: pypi, with optional manual-approval gate)
  - release.published (prerelease) OR workflow_dispatch target=testpypi
    -> publishes to TestPyPI (environment: testpypi, staging/verification)
  - workflow_dispatch target=build-only -> builds + twine-checks, no
    network publish (credential-free dry run)

Every path runs the same build job first: python -m build, twine
check --strict, install the wheel in a clean venv, run the full
pytest suite against the installed wheel. Only if the wheel itself
passes the test suite does anything get uploaded. The production
job additionally verifies that the GitHub Release tag (v0.X.Y)
matches __version__ in the package and refuses to publish on
mismatch — preventing accidental version drift.

Trusted Publishing was chosen over API tokens because:

  - No secrets to rotate or leak.
  - Scoped per environment: the pypi environment can be gated with
    required reviewers and tag-only deployment branches.
  - PyPI binds the trust to (owner, repo, workflow filename,
    environment), so a fork or a different workflow cannot publish
    on your behalf even if it runs on this repo.

The one-time setup (register Trusted Publisher on PyPI and pending
publisher on TestPyPI, create pypi + testpypi GitHub Environments)
is documented in the new docs/RELEASE.md, along with the routine
release checklist, version-bump convention, and recovery procedure
for bad releases.

build + twine added to requirements-dev.txt so contributors can
reproduce the build locally before opening a release PR.



* chore: add OSS community health files

- Issue templates (bug report, feature request, Maithili keyword proposal)
- CODE_OF_CONDUCT.md (Contributor Covenant 2.1)
- SUPPORT.md and issue template contact links (security reporting routed privately)
- CODEOWNERS for security-sensitive paths
- Label guide in CONTRIBUTING.md; CoC links in README/CONTRIBUTING
- Mark BACKLOG.md as historical (tracking moved to GitHub Issues)



* ci: add ci-ok aggregate gate job + Dependabot config

- ci-ok: single required-status-check target that fails if any test
  matrix leg fails, so branch protection survives matrix changes
- dependabot.yml: weekly github-actions + pip updates targeting
  development, labeled infra/needs-triage



* fix(linter): accept augmented assignments

Strip augmented-assignment operators before validating the target name. Add regression coverage for every reported arithmetic operator.

* chore(deps): bump actions/upload-artifact from 4 to 7 (#14)

Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...




* chore(deps): bump actions/setup-python from 5 to 6 (#15)

Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...




* chore(deps): bump actions/checkout from 4 to 7 (#16)

Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...




* chore(deps): bump actions/download-artifact from 4 to 8 (#17)

Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](actions/download-artifact@v4...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...




* chore(deps-dev): update twine requirement from <6,>=4.0 to >=6.2.0,<7 (#18)

Updates the requirements on [twine](https://github.com/pypa/twine) to permit the latest version.
- [Release notes](https://github.com/pypa/twine/releases)
- [Changelog](https://github.com/pypa/twine/blob/main/docs/changelog.rst)
- [Commits](pypa/twine@4.0.0...6.2.0)

---
updated-dependencies:
- dependency-name: twine
  dependency-version: 6.2.0
  dependency-type: direct:development
...




* chore(deps-dev): update pytest-cov requirement (#20)

Updates the requirements on [pytest-cov](https://github.com/pytest-dev/pytest-cov) to permit the latest version.
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](pytest-dev/pytest-cov@v4.1.0...v7.1.0)

---
updated-dependencies:
- dependency-name: pytest-cov
  dependency-version: 7.1.0
  dependency-type: direct:development
...




* chore(deps-dev): update pytest-timeout requirement (#21)

Updates the requirements on [pytest-timeout](https://github.com/pytest-dev/pytest-timeout) to permit the latest version.
- [Commits](pytest-dev/pytest-timeout@2.2.0...2.4.0)

---
updated-dependencies:
- dependency-name: pytest-timeout
  dependency-version: 2.4.0
  dependency-type: direct:development
...




* chore: drop Python 3.9 support (EOL Oct 2025) (#52)

Removes 3.9 from the CI matrix, bumps requires-python to >=3.10, drops
the 3.9 classifier from pyproject.toml and setup.py, and updates the
README support line. Unblocks Dependabot PRs #19 (pytest 9) and #22
(build 1.5) which dropped 3.9 support.

Closes #44



* chore(deps-dev): update pytest requirement from <9,>=7.4 to >=9.1.1,<10 (#19)

Updates the requirements on [pytest](https://github.com/pytest-dev/pytest) to permit the latest version.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@7.4.0...9.1.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 9.1.1
  dependency-type: direct:development
...




* chore(deps-dev): update build requirement from <2,>=1.0 to >=1.5.0,<2 (#22)

Updates the requirements on [build](https://github.com/pypa/build) to permit the latest version.
- [Release notes](https://github.com/pypa/build/releases)
- [Changelog](https://github.com/pypa/build/blob/main/CHANGELOG.rst)
- [Commits](pypa/build@1.0.0...1.5.0)

---
updated-dependencies:
- dependency-name: build
  dependency-version: 1.5.0
  dependency-type: direct:development
...




* fix(linter): detect real function call sites (#48)

* fix(linter): detect real function call sites

Match declared functions at Devanagari-aware identifier boundaries and ignore string/comment contents when checking usage. Add regressions for longer identifiers and string literals.

* docs(changelog): note function-as-value trade-off for unused check

* docs: add examples/README.md describing each example program (fixes #41) (#47)




* ci: enforce coverage gate with fail_under = 85 (fixes #42) (#46)




* release: v0.4.0 (#53)

Bump version to 0.4.0 across __init__.py, pyproject.toml (setup.py reads
from __init__). Finalize CHANGELOG: promote [Unreleased] to [0.4.0] dated
2026-07-23, consolidate the fixed entries, and add the coverage-gate (#42)
and examples README (#41) entries that were merged without changelog lines.

First PyPI publish since 0.2.0 (0.3.0 was never pushed to the index).



---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Bishwas Jha <bishwasjha@Bishwass-MacBook-Pro.local>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Sanjay Santhanam <51058514+Sanjays2402@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MOHAMMED HANAN M T P <91409429+hanu-14@users.noreply.github.com>
Co-authored-by: MOHAMMED HANAN M T P <hanu@example.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:linter maithili_dsl/transpiler/linter.py bug Something isn't working P3 Low priority: nice to have

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Unused-function check uses substring match — false negatives for Devanagari names

2 participants